<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/21 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

namespace api\modules\v1\forms;

use common\models\User;
use Yii;
use common\models\BaseModel;

/**
 * User模型注册表单
 * Class UserForm
 * @package api\modules\v1\forms
 */
class UserRegisterForm extends BaseModel
{
    public $mobile;                 // 用户账号手机号
    public $countryCode = 86;       // 用户账号手机号国家代码: 86(中国)
    public $nickname;               // 用户账号昵称
    public $password;               // 用户账号密码

    private $_user = null;          // 用户对象

    /**
     * 表单字段规则
     * @return array
     */
    public function rules()
    {
        return [
            [['mobile', 'nickname', 'password'], 'trim'],
            [['countryCode'], 'number', 'skipOnError' => true],
            [['mobile', 'countryCode', 'nickname', 'password'], 'required'],
            ['mobile', 'validateMobile', 'skipOnError' => true], // 行内验证器 检测手机号码格式
            ['password', 'validatePassword', 'skipOnError' => true], // 行内验证器 检测密码强度
            // 限制手国家代码+机号码唯一
            [
                ['mobile'],
                'unique',
                'skipOnError' => true,
                'targetClass' => User::class,
                'targetAttribute' => ['mobile', 'countryCode' => 'country_code'],
                // 自定义错误消息
                'message' => Yii::t('common', 'Mobile "{value}" has already been taken.')
            ],
            // 限制昵称唯一
            [
                ['nickname'],
                'unique',
                'skipOnError' => true,
                'targetClass' => User::class,
                'targetAttribute' => ['nickname'],
                'message' => Yii::t('common', 'Nickname "{value}" has already been taken.')
            ],
        ];
    }

    /**
     * 检测手机号码格式
     * @param string $attribute 当前检测的字段名
     * @param array $params 以名-值对形式提供的额外参数
     * @param \yii\validators\InlineValidator $validator 当前行内验证器 InlineValidator实例。此参数自版本 2.0.11 起可用。
     */
    public function validateMobile($attribute, $params, $validator)
    {
        if (!$this->hasErrors()) {
            if (!Yii::$app->utils->regExp($this->$attribute, 'cn_mobile')) {
                $validator->addError($this, $attribute, Yii::t('common', 'The mobile "{value}" is invalid.'));
            }
        }
    }

    /**
     * 检测密码强度
     * @param string $attribute 当前检测的字段名
     * @param array $params 以名-值对形式提供的额外参数
     * @param \yii\validators\InlineValidator $validator 当前行内验证器 InlineValidator实例。此参数自版本 2.0.11 起可用。
     */
    public function validatePassword($attribute, $params, $validator)
    {
        if (!$this->hasErrors()) {
            if (!Yii::$app->utils->regExp($this->$attribute, 'power_password')) {
                $this->addError($attribute, Yii::t('common', 'The password is invalid.'));
            }
        }
    }

    /**
     * 返回用户对象
     * @return null|@common\models\User
     */
    public function getUser()
    {
        return $this->_user;
    }

    /**
     * 注册账号
     * @return bool
     */
    public function register()
    {
        // 打开数据库事务
        $trans  = Yii::$app->getDb()->beginTransaction();
        try {
            // rules()规则都验证通过
            if ($this->validate()) {
                $user = new User();
                $user->mobile = $this->mobile;
                $user->nickname = $this->nickname;
                $user->country_code = $this->countryCode;
                $user->generateAccessToken(); // 生成api接口token
                $user->setPassword($this->password); // 生成密码
                $user->created_at = $user->updated_at = date('Y-m-d H:i:s');

                if ($user->save(false)) {
                    // 创建用户成功 提交事务
                    $trans->commit();
                    $this->_user = $user; // 保存用户对象
                    return true;
                }
            }
            // 创建失败 数据库回滚
            $trans->rollBack();
        } catch(\Exception $e) {
            $trans->rollBack();
        }
        return false;
    }
}
